﻿#include "custom_data.h"
#include <iostream>
#include <sstream>

using namespace boost::interprocess;

custom_data::custom_data()
{
}

void custom_data::init(managed_shared_memory &segment)
{
    a_ptr_ = segment.find_or_construct<int>("custom_data_a_ptr")(0);
    *a_ptr_ = 0;
    a_mutex_ptr_ = segment.find_or_construct<interprocess_mutex>("custom_data_a_mutex_ptr")();

    // const shmem_vector_allocator alloc_inst(segment.get_segment_manager());
    // b_ptr_ = segment.find_or_construct<my_vector>("custom_data_b_ptr")(alloc_inst);
    // const shmem_map_allocator alloc_inst(segment.get_segment_manager());
    // b_ptr_ = segment.find_or_construct<my_map>("custom_data_b_ptr")(alloc_inst);
    // std::cout << b_ptr_ << std::endl;

    const shmem_std_unordered_map_allocator alloc_inst(segment.get_segment_manager());
    b_ptr_ = segment.find_or_construct<my_std_unordered_map>("custom_data_b_ptr")(alloc_inst);
    std::cout << b_ptr_ << std::endl;
    b_mutex_ptr_ = segment.find_or_construct<interprocess_mutex>("custom_data_b_mutex_ptr")();
    std::cout << b_mutex_ptr_ << std::endl;
    b_cond_ptr_ = segment.find_or_construct<interprocess_condition>("custom_data_b_cond_ptr")();

    v_s_ptr = segment.find_or_construct<vector_string>("custom_data_v_s_ptr")(alloc_inst);

    if (b_ptr_->find(1111) != b_ptr_->end())
    {
        std::cout << "find" << std::endl;
        int *p = (int *)((uint64_t)segment.get_address() + (*b_ptr_)[1111]);
        std::cout << *p << std::endl;
    }
    else
    {
        int *ptr = (int *)segment.allocate(4);
        *ptr = 999;
        b_ptr_->insert(value_type(1111, (uint64_t)ptr - (uint64_t)segment.get_address()));
        std::cout << "insert" << std::endl;
    }

    sub_info_set_ptr_ = segment.find_or_construct<SubInfoSet>("custom_data_sub_info_set_ptr")(alloc_inst);
}

void custom_data::add()
{
    scoped_lock<interprocess_mutex> lock(*a_mutex_ptr_);
    (*a_ptr_)++;
}

void custom_data::push_back(int num)
{
    std::cout << "push_back 1" << std::endl;
    scoped_lock<interprocess_mutex> lock(*b_mutex_ptr_);
    // b_ptr_->insert(value_type(num, num));
    // b_cond_ptr_->notify_one();

    SubInfo sub_info;
    sub_info.bev_session_id = num;
    sub_info.formular_id = num + 1;
    sub_info.topic = num + 2;
    sub_info_set_ptr_->insert(sub_info);
}

void custom_data::push_back(std::string str)
{
    v_s_ptr->push_back(boost::interprocess::string(str.data(), str.size()));
}

// std::vector<int> custom_data::pop_all(std::size_t &index) {
//     scoped_lock<interprocess_mutex> lock(*b_mutex_ptr_);
//     if (index == b_ptr_->size()) {
//         // std::cout << "pop_all" << std::endl;
//         b_cond_ptr_->wait(lock);
//     }
//     std::vector<int> ret;
//     for (std::size_t i = index; i < b_ptr_->size(); ++i) {
//         ret.push_back((*b_ptr_)[i]);
//     }
//     index = b_ptr_->size();
//     return ret;
// }

std::vector<uint64_t> custom_data::pop_all()
{
    std::cout << "pop_all1" << std::endl;
    scoped_lock<interprocess_mutex> lock(*b_mutex_ptr_);
    std::vector<uint64_t> ret;
    auto &&index = get<0>(*sub_info_set_ptr_);
    for (auto it = index.begin(); it != index.end(); ++it)
    {
        ret.push_back(it->bev_session_id);
        ret.push_back(it->formular_id);
        ret.push_back(it->topic);
    }
    index.clear();
    return ret;
}

// std::vector<std::string> custom_data::pop_all()
// {
//     std::cout << "pop_all1" << std::endl;
//     scoped_lock<interprocess_mutex> lock(*b_mutex_ptr_);
//     std::vector<std::string> ret;
//     for (auto it = v_s_ptr->begin(); it != v_s_ptr->end(); ++it)
//     {
//         ret.push_back(std::string(it->data(), it->size()));
//     }
//     v_s_ptr->clear();
//     return ret;
// }

void custom_data::print()
{
    std::cout << "a_ptr:" << *a_ptr_ << std::endl;
    std::cout << a_ptr_ << std::endl;
    std::cout << "b_ptr size:" << b_ptr_->size() << std::endl;
    std::ostringstream oss;
    int cnt = 0;
    for (auto it = b_ptr_->begin(); it != b_ptr_->end() && cnt < 200; ++it)
    {
        // oss << *it << ",";
        cnt++;
    }
    std::cout << oss.str() << std::endl;
}